package com.heima.comment.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.heima.client.article.IArticleClient;
import com.heima.client.user.IUserClient;
import com.heima.client.wemedia.IWemediaClient;
import com.heima.comment.receive.pojos.ApComment;
import com.heima.comment.receive.pojos.ApCommentLike;
import com.heima.comment.receive.vo.ApCommentVo;
import com.heima.comment.service.ApCommentService;
import com.heima.common.exception.CustomException;
import com.heima.model.common.dtos.ArticleDto;
import com.heima.model.common.dtos.CommentLikeDto;
import com.heima.model.common.dtos.CommentSaveDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.common.pojos.article.ApArticle;
import com.heima.utils.thread.ApThreadLocalUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.heima.model.common.pojos.user.ApUser;
import org.springframework.data.mongodb.core.query.Update;

/**
 *
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ApCommentServiceImpl implements ApCommentService {
    @Autowired
    private IWemediaClient wemediaClient;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private IArticleClient articleClient;
    @Autowired
    private IUserClient userClient;

    /**
     * 保存评论
     *
     * @param commentSaveDto
     * @return
     */
    @Override
    public ResponseResult save(CommentSaveDto commentSaveDto) {
        //参数校验
        if (commentSaveDto == null || commentSaveDto.getArticleId() == null || commentSaveDto.getContent() == null)
            throw new CustomException(AppHttpCodeEnum.AP_USER_DATA_NOT_EXIST);
        if(commentSaveDto.getMinDate()==null)
            commentSaveDto.setMinDate(new Date());
        //1.判断当前登录的用户---正常继续流程，非正常直接返回
        Integer userId = ApThreadLocalUtil.get();
        //1.1 如果是非正常用户---需登录后才能操作,直接返回
        if (userId == null || userId == 0)
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        //2.评论内容不能超过140字
        if (commentSaveDto.getContent().length() > 140)
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        //3.文本敏感词检测
        String content = commentSaveDto.getContent();
        ResponseResult responseResult = wemediaClient.autoScan(content);
        boolean textIsPass = (boolean) responseResult.getData();
        if (!textIsPass) return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        //4.创建apComment实体，准备保存数据
        ApComment apComment = new ApComment();
        //4.1根据文章id查找作者信息
        ResponseResult result1 = userClient.queryUser(userId);
        ApUser apUser = JSON.parseObject(JSON.toJSONString(result1.getData()), ApUser.class);
        apComment.setAuthorId(Long.valueOf(userId));
        apComment.setAuthorName(apUser.getName());
        //4.2是否关注作者（是否为粉丝）
        Long articleId = commentSaveDto.getArticleId();
        ResponseResult response = articleClient.queryArticle(articleId);
        ApArticle apArticle = JSON.parseObject(JSON.toJSONString(response.getData()), ApArticle.class);
        ResponseResult result = userClient.isFan(userId, apArticle.getAuthorId());
        Integer type = JSON.parseObject(JSON.toJSONString(result.getData()), Integer.class);
        if (type == null || type == 0) {
            apComment.setType(0);
        } else {
            apComment.setType(1);
        }
        apComment.setCreatedTime(new Date());
        apComment.setReply(0);
        apComment.setFlag(1);
        apComment.setLikes(0L);
        apComment.setEntryId(commentSaveDto.getArticleId());
        apComment.setContent(commentSaveDto.getContent());
        //4.4创建apComment实体，并保存数据,保存数据到MongoDB中
        mongoTemplate.save(apComment);
        //5.文章评论数量+1
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(apArticle,articleDto);
        if (apArticle.getComment()==null){
            apArticle.setComment(1);
        }else {
            apArticle.setComment(apArticle.getComment()+1);
        }
        articleClient.syncArticle(articleDto);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 评论列表
     *
     * @param commentSaveDto
     * @return
     */
    @Override
    public ResponseResult load(CommentSaveDto commentSaveDto) {
        //校验参数
        if (commentSaveDto == null || commentSaveDto.getArticleId() == null) {
            throw new CustomException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        if (commentSaveDto.getMinDate() == null)
            commentSaveDto.setMinDate(new Date());
        //1.从mongodb分页查询ApComment的最新时间10条数据
        List<ApComment> apCommentList = mongoTemplate.find(Query.query(Criteria
                        .where("entryId").is(commentSaveDto.getArticleId()).and("createdTime").lt(commentSaveDto.getMinDate()))
                .with(Sort.by(Sort.Direction.DESC, "createdTime")).limit(10), ApComment.class);
        //2.数据填充
        List<ApCommentVo> commentVoList = new ArrayList<>();
        for (ApComment comment : apCommentList) {
            ApCommentVo apCommentVo = new ApCommentVo();
            BeanUtils.copyProperties(comment, apCommentVo);
            apCommentVo.setUpdatedTime(comment.getCreatedTime());
            apCommentVo.setChannelId(0);
            apCommentVo.setImage(null);
            apCommentVo.setLongitude(0);
            apCommentVo.setLatitude(0);
            apCommentVo.setAddress(0);
            apCommentVo.setOrd(null);
            //2.1查看用户是否点赞评论
            ApCommentLike commentLike = mongoTemplate.findOne(Query.query(Criteria
                    .where("authorId").is(Long.valueOf(ApThreadLocalUtil.get()))
                    .and("commentId").is(comment.getId())), ApCommentLike.class);
            if (commentLike != null)
                apCommentVo.setOperation((short) 0);
            //2.3添加进集合
            commentVoList.add(apCommentVo);
        }
        return ResponseResult.okResult(commentVoList);
    }


    /**
     * 评论点赞
     *
     * @param commentLikeDto
     * @return
     */
    @Override
    public ResponseResult like(CommentLikeDto commentLikeDto) {
//        if (commentLikeDto == null || commentLikeDto.getCommentId() == null || commentLikeDto.getOperation() == null)
//            throw new CustomException(AppHttpCodeEnum.PARAM_REQUIRE);
//        //判断当前登录的用户---正常继续流程，非正常直接返回
//        Integer userId = ApThreadLocalUtil.get();
//        //如果是非正常用户---需登录后才能操作,直接返回
//        if (userId == null || userId == 0)
//            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
//        //1.判断是否为点赞
//        //1.1.点赞
//        if (commentLikeDto.getOperation() == (short) 0) {
//            //修改作者的评论点赞数
//            ApCommentLike apCommentLike = new ApCommentLike();
//            apCommentLike.setCommentId(commentLikeDto.getCommentId());
//            apCommentLike.setAuthorId(Long.valueOf(userId));
//            commentLikeUpdate(commentLikeDto, 1);
//            //新增用户的点赞数据
//            mongoTemplate.save(apCommentLike);
//        } else if (commentLikeDto.getOperation() == (short) 1) {
//            //1.2取消点赞
//            //修改作者的评论点赞数
//            commentLikeUpdate(commentLikeDto, -1);
//            //删除用户的点赞数据
//            mongoTemplate.remove(Query.query(
//                            Criteria.where("commentId")
//                                    .is(commentLikeDto.getCommentId())),
//                    ApCommentLike.class);
//        }
//        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
        String commentId = commentLikeDto.getCommentId();
        //获取当前作者ID
        Integer userId = ApThreadLocalUtil.get();
        //根据评论ID查询当前回复评论信息
        ApComment apComment = mongoTemplate.findOne(
                Query.query(Criteria.where("id")
                        .is(commentId)),
                ApComment.class);
        //校验当然评论是否存在
        if (ObjectUtils.isEmpty(apComment)) {
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (commentLikeDto.getOperation() == (short)0) {
            //1.1修改当前评论的like字段+1
            apComment.setLikes(apComment.getLikes() + 1);
            mongoTemplate.updateFirst(
                    Query.query(Criteria.where("commentId")
                            .is(commentId)),
                    new Update()
                            .set("likes", apComment.getLikes()),
                    ApComment.class);
            //1.2将作者信息保存到ap_comment_like中
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setAuthorId(Long.valueOf(userId));
            apCommentLike.setCommentId(apComment.getId());
            mongoTemplate.save(apCommentLike);
        } else {
            //2取消点赞
            //2取消点赞
            long tmp = apComment.getLikes() - 1;
            tmp = tmp < 1 ? 0 : tmp;
            apComment.setLikes(tmp);
            mongoTemplate.save(apComment);
            //删除ap_comment_like表中的数据
            mongoTemplate.remove(Query.query(
                            Criteria.where("commentId")
                                    .is(apComment.getId())),
                    ApCommentLike.class);
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }


    /**
     * 更新作者的评论点赞数
     *
     * @param commentLikeDto
     * @param num
     */
    private void commentLikeUpdate(CommentLikeDto commentLikeDto, int num) {
        ApComment apComment = mongoTemplate.findOne(Query.query(Criteria.where("commentId")
                .is(commentLikeDto.getCommentId())), ApComment.class);
        //1.增加/减少评论用户的评论点赞数
        if (apComment.getLikes()==null){
            apComment.setLikes(0L);
        }
        apComment.setLikes(apComment.getLikes() + num);
        if (apComment.getLikes()<0){
            apComment.setLikes(0L);
        }
        mongoTemplate.save(apComment);
    }
}
